
// 从Java 8开始，java.time包提供了新的日期和时间API，主要涉及的类型有：
// 本地日期和时间：LocalDateTime，LocalDate，LocalTime；
// 带时区的日期和时间：ZonedDateTime；
// 时刻：Instant；
// 时区：ZoneId，ZoneOffset；
// 时间间隔：Duration。

import java.time.*;

public class Test {
    public static void main(String[] args) {
        // LocalDateTime
        LocalDateTime dt = LocalDateTime.now(); // 当前日期和时间
        LocalDate d = dt.toLocalDate(); // 转换到当前日期
        LocalTime t = dt.toLocalTime(); // 转换到当前时间
        System.out.println(d); // 严格按照ISO 8601格式打印
        System.out.println(t); // 严格按照ISO 8601格式打印
        System.out.println(dt); // 严格按照ISO 8601格式打印
        // 指定日期和时间
        LocalDate d2 = LocalDate.of(2019, 11, 30); // 2019-11-30, 注意11=11月
        LocalTime t2 = LocalTime.of(15, 16, 17); // 15:16:17
        LocalDateTime dt2 = LocalDateTime.of(2019, 11, 30, 15, 16, 17);
        LocalDateTime dt3 = LocalDateTime.of(d2, t2);
        System.out.println(dt2);
        System.out.println(dt3);
        // 解析字符串
        LocalDateTime dt4 = LocalDateTime.parse("2019-11-19T15:16:17");
        LocalDate d4 = LocalDate.parse("2019-11-19");
        LocalTime t4 = LocalTime.parse("15:16:17");
        System.out.println(dt4);
        System.out.println(d4);
        System.out.println(t4);

        // DateTimeFormatter
        // // 自定义格式化:
        var dtf = java.time.format.DateTimeFormatter.ofPattern("yyyy/MM/dd HH-mm-ss");
        String strDate = dtf.format(dt4);
        System.out.println(strDate);
        // 用自定义格式解析:
        LocalDateTime dt5 = LocalDateTime.parse("2019/11/19 15-16-17", dtf);
        System.out.println(dt5);

        // LocalDateTime提供了对日期和时间进行加减的非常简单的链式调用：
        LocalDateTime dt6 = dt4.plusDays(2).minusHours(3).plusMinutes(15);
        System.out.println(dt6);

        // 对日期和时间进行调整则使用withXxx()方法，例如：withHour(15)会把10:11:12变为15:11:12：
        // 调整年：withYear()
        // 调整月：withMonth()
        // 调整日：withDayOfMonth()
        // 调整时：withHour()
        // 调整分：withMinute()
        // 调整秒：withSecond()
        LocalDateTime dt7 = dt4.withHour(15).withMinute(0).withSecond(0);
        System.out.println(dt7);

        // LocalDateTime还有一个通用的with()方法允许我们做更复杂的运算。例如
        // 把日期调整到本月的第一个星期一：
        LocalDateTime dt8 = dt4.with(java.time.temporal.TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
        System.out.println(dt8);

        // Duration和Period
        // Duration表示两个时刻之间的时间间隔。另一个类似的Period表示两个日期之间的天数：
        LocalDateTime start = LocalDateTime.of(2019, 11, 19, 10, 11, 12);
        LocalDateTime end = LocalDateTime.of(2020, 1, 1, 15, 16, 17);
        Duration dur = Duration.between(start, end);
        System.out.println("Duration: " + dur.toDays() + "天");
        Period per = Period.between(start.toLocalDate(), end.toLocalDate());
        System.out.println("Period: " + per.getMonths() + "个月" + per.getDays() + "天");


        // 使用isBefore()和isAfter()可以判断日期和时间的先后
        System.out.println(start.isBefore(end)); // true
        System.out.println(start.isAfter(end)); // false
    }

}

// 注意ISO 8601规定的日期和时间分隔符是T。标准格式如下：

// 日期：yyyy-MM-dd
// 时间：HH:mm:ss
// 带毫秒的时间：HH:mm:ss.SSS
// 日期和时间：yyyy-MM-dd'T'HH:mm:ss
// 带毫秒的日期和时间：yyyy-MM-dd'T'HH:mm:ss.SSS